import { NodeStatus } from "../NodeStatus";
import { INodeConfig } from "../interfaces/INodeConfig";
import { DecoratorNode } from "./DecoratorNode";


/**
 * 在设置的msec 毫秒内，返回子节点执行的状态。
 * 若子节点返回FAILURE或SUCCESS，不再执行。
 * 如果超时，终止子节点执行，并返回FAILURE。
 */
export class TimeOutNode<T> extends DecoratorNode<T> {
    private timerHandler: number | undefined;
    private child_halted: boolean;
    private msec: number;
    private timeout_started: boolean;

    constructor(name: string, blackboard: T) {
        super(name, blackboard);
        this.child_halted = false;
        this.timeout_started = false;
    }

    Init(data: INodeConfig): void {
        if (data.hasOwnProperty('msec')) {
            // @ts-ignore
            this.msec = data['msec'];
        }
    }

    Tick(): NodeStatus {
        if (!this.timeout_started) {
            this.timeout_started = true;
            this.status = NodeStatus.RUNNING;
            this.child_halted = false;

            if (this.msec > 0) {
                this.timerHandler = setTimeout(() => {
                    if (this.GetChild()!.status == NodeStatus.RUNNING) {
                        this.child_halted = true;
                        this.HaltChild();
                    }
                }, this.msec);
            }
        }

        if (this.child_halted) {
            this.timeout_started = false;
            return NodeStatus.FAILURE;
        } else {
            const child_status = this.GetChild()!.Evaluate();
            if (child_status != NodeStatus.RUNNING) {
                this.timeout_started = false;
                if (this.timerHandler) {
                    clearTimeout(this.timerHandler);
                    this.timerHandler = undefined;
                }
            }
            return child_status;
        }
    }
}
